package com.member.server.domain.vo;

import com.alibaba.fastjson.JSON;
import com.member.server.domain.dto.MemAccLogInfoDTO;
import com.member.server.entity.AccountLog;
import com.member.server.entity.Record;
import com.member.server.enums.RecordType;

import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author gaojx1993
 * @version 1.0
 * @description MemAccLogVO
 * @since 2023/7/12 11:53
 */
public class MemAccLogVO implements Serializable {

    private Long memberId;

    private String memberName;

    private List<AccLogInfo> accLogInfos;

    public static MemAccLogVO copy(MemAccLogInfoDTO memAccLogInfoDTO) {
        MemAccLogVO memAccLogVO = new MemAccLogVO();
        memAccLogVO.setMemberId(memAccLogInfoDTO.getMember().getId());
        memAccLogVO.setMemberName(memAccLogInfoDTO.getMember().getName());
        List<AccountLog> accountLogs = memAccLogInfoDTO.getAccountLogs();
        List<Record> records = memAccLogInfoDTO.getRecords();
        List<AccLogInfo> accLogInfos = new ArrayList<>(accountLogs.size());
        accountLogs.forEach(al -> {
            AccLogInfo accLogInfo = new AccLogInfo();
            accLogInfo.setId(al.getId());
            accLogInfo.setAccountId(al.getAccountId());
            accLogInfo.setRecordId(al.getRecordId());
            accLogInfo.setBeforeBalance(al.getBeforeBalance());
            accLogInfo.setAfterBalance(al.getAfterBalance());
            accLogInfo.setCreateTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(al.getGmtCreate()), ZoneId.systemDefault()));
            accLogInfo.setChangeAmount(Math.abs(al.getAfterBalance() - al.getBeforeBalance()));
            Optional<Record> any = records.stream().filter(r -> Objects.equals(r.getId(), al.getRecordId())).findAny();
            if (any.isPresent()) {
                Record record = any.get();
                accLogInfo.setType(record.getType());
                RecordType recordType = RecordType.findByCode(record.getType());
                accLogInfo.setTypeTag(recordType == null ? null : recordType.name());
            }
            accLogInfos.add(accLogInfo);
        });
        memAccLogVO.setAccLogInfos(accLogInfos);
        return memAccLogVO;
    }

    public Long getMemberId() {
        return memberId;
    }

    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }

    public String getMemberName() {
        return memberName;
    }

    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    public List<AccLogInfo> getAccLogInfos() {
        return accLogInfos;
    }

    public void setAccLogInfos(List<AccLogInfo> accLogInfos) {
        this.accLogInfos = accLogInfos;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

    public static class AccLogInfo implements Serializable {

        private Long id;

        private Long accountId;

        private Long recordId;

        private LocalDateTime createTime;

        private Integer type;

        private String typeTag;

        private Long changeAmount;

        private Long beforeBalance;

        private Long afterBalance;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public Long getAccountId() {
            return accountId;
        }

        public void setAccountId(Long accountId) {
            this.accountId = accountId;
        }

        public Long getRecordId() {
            return recordId;
        }

        public void setRecordId(Long recordId) {
            this.recordId = recordId;
        }

        public LocalDateTime getCreateTime() {
            return createTime;
        }

        public void setCreateTime(LocalDateTime createTime) {
            this.createTime = createTime;
        }

        public Integer getType() {
            return type;
        }

        public void setType(Integer type) {
            this.type = type;
        }

        public String getTypeTag() {
            return typeTag;
        }

        public void setTypeTag(String typeTag) {
            this.typeTag = typeTag;
        }

        public Long getChangeAmount() {
            return changeAmount;
        }

        public void setChangeAmount(Long changeAmount) {
            this.changeAmount = changeAmount;
        }

        public Long getBeforeBalance() {
            return beforeBalance;
        }

        public void setBeforeBalance(Long beforeBalance) {
            this.beforeBalance = beforeBalance;
        }

        public Long getAfterBalance() {
            return afterBalance;
        }

        public void setAfterBalance(Long afterBalance) {
            this.afterBalance = afterBalance;
        }

        @Override
        public String toString() {
            return JSON.toJSONString(this);
        }
    }
}
